/**
 * @addtogroup pfc_mwsr_ring_queue.h
 * pfc_mwsr_ring_queue.h
 * @{
 */
/**
 * @file pfc_mwsr_ring_queue.h
 * @brief 支持多写单读的循环队列,多线程和中断操作写均安全,仅允许一个线程或者中断读取
 * @author Leo
 * @date 2020-4-2
 * @version 1.0

 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2020-4-2    <td>1.0                   <td>Leo             <td>创建初始版本
 * @copyright 杭州鸿泉物联网技术股份有限公司
 */

#ifndef _PFC_MWSR_RING_QUEUE_H_
#define _PFC_MWSR_RING_QUEUE_H_

#include "ofc_ring_queue.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 构造一个单线程读取,多线程写入的循环缓冲区对象
 * @par 示例
 * @code
   void *items[64];
   TPfMwSrRingQueue queue;
   TPfMwSrRingQueueCreate(&queue, items, sizeof(items) / sizeof(items[0]));
   // ...
   // 采用相应的方法销毁对象
   OfDestroyObject((TOfObject *)&queue);

 thread1:
   void *item;
   ...
   TPfMwSrRingQueuePush(&queue, item);

 thread2:
    void *item = TPfMwSrRingQueuePop(&queue);
    ...
 * @endcode
*/
typedef struct TPfMwSrRingQueueTag TPfMwSrRingQueue;
struct TPfMwSrRingQueueTag
{
PROTECTED
    TOfObject parent_; ///<基类
    TOfVirtualMethod Destroy_; ///<析构函数

PRIVATE
    TOfRingQueue queue_;  ///< 队列对象
};

/**
 * 类的构造函数
 * @param self: 对象实例指针
 * @param items: 用于存放队列项的缓冲区
 * @param item_count: items中可以存放的队列项数
 * @return 返回创建是否成功; 创建成功返回True,参数错误创建失败返回False
 */
Bool TPfMwSrRingQueueCreate(TPfMwSrRingQueue *self, void *items, Int32 item_count);

/**
 * 创建一个环形队列
 * @param items: 用于存放队列项的缓冲区
 * @param item_count: items中可以存放的队列项数
 * @return 返回创建的对象,创建失败返回NULL
 */
TPfMwSrRingQueue *PfCreateMwSrRingQueue(void *items, Int32 item_count);

/**
 * 压一个队列项到队列
 * @note 仅用于单线程(中断)操作
 * @param self: 对象实例
 * @param item: 压入的队列项
 * @return 压入成功返回True,否则返回False
 */
Bool TPfMwSrRingQueuePush(TPfMwSrRingQueue *self, const void *item);

/**
 * 取出队列中最前面的项,该项将从队列中移除
 * @note 仅用于单线程(中断)操作
 * @param self: 对象实例
 * @return 返回取出的项
 */
void *TPfMwSrRingQueuePop(TPfMwSrRingQueue *self);

/**
 * 读出队列中最前面的项,该项不从队列中移除
 * @note 仅用于单线程(中断)操作
 * @param self: 对象实例
 * @return 返回队列项; 如果队列为空,返回NULL
 */
void *TPfMwSrRingQueuePeek(TPfMwSrRingQueue *self);

/**
 * 清除所有写入队列项目
 * @note 仅用于单线程(中断)操作,且必须和调用[TPfMwSrRingQueuePop](@ref TPfMwSrRingQueuePop)的线程(中断)是同一个线程(中断)
 * @param self: 对象实例
 * @return 无返回值
 */
void TPfMwSrRingQueueClear(TPfMwSrRingQueue *self);

/**
 * 返回队列项的总数(包括数据项和空闲项目,等于构造函数的参数item_count)
 * @param self: 对象实例
 * @return 返回队列项的总数
 */
Int32 TPfMwSrRingQueueSize(TPfMwSrRingQueue *self);

/**
 * 返回空闲项个数
 * @param self: 对象实例
 * @return 返回空闲项个数
 */
Int32 TPfMwSrRingQueueFreeCount(TPfMwSrRingQueue *self);

/**
 * 返回当前队列中队列项的个数
 * @param self: 对象实例
 * @return 返回队列项个数
 */
Int32 TPfMwSrRingQueueCount(TPfMwSrRingQueue *self);

#ifdef __cplusplus
}  // extern "C"
#endif

#endif // _PFC_MWSR_RING_QUEUE_H_

/**
 * @}
 */
